﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Pahan.McuFusion.Common;

namespace Pahan.McuFusion.UI.Workspaces
{
    public sealed partial class Workspace : IDisposable
    {
        #region Constructors

        public Workspace(DeviceInfo device, ProgrammerInfo programmer, 
            HardwareAdapterInfo adapter, HardwareInterfaceInfo @interface)
        {
            Assert.NotNull(device, "device");
            Assert.NotNull(programmer, "programmer");
            Assert.NotNull(adapter, "adapter");
            Assert.NotNull(@interface, "interface");
            this.DeviceInfo = device;
            this.ProgrammerInfo = programmer;
            this.HardwareAdapterInfo = adapter;
            this.HardwareInterfaceInfo = @interface;
            this.Name = "Workspace " + (++workspaceCounter);
        }

        #endregion

        #region Public Methods

        public void Initialize()
        {
            hwInterface = HardwareInterfaceInfo.CreateInterface();
            adapter = HardwareAdapterInfo.CreateAdapter(hwInterface);
            programmer = ProgrammerInfo.CreateProgrammer(DeviceInfo, adapter);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (programmer != null)
            {
                programmer.Dispose();
            }
        }

        public Object GetOptions()
        {
            if (options == null)
            {
                options = new Options(this);
            }
            return options;
        }

        public void SetModified()
        {
            Modified = true;
        }

        #endregion

        #region Public Properties

        public DeviceInfo DeviceInfo
        {
            get;
            private set;
        }

        public ProgrammerInfo ProgrammerInfo
        {
            get;
            private set;
        }

        public HardwareAdapterInfo HardwareAdapterInfo
        {
            get;
            private set;
        }

        public HardwareInterfaceInfo HardwareInterfaceInfo
        {
            get;
            private set;
        }

        public IProgrammer Programmer
        {
            get
            {
                if (programmer == null)
                {
                    throw new InvalidOperationException("Call Initialize before accessing this property.");
                }
                return programmer;
            }
        }

        public String Name
        {
            get;
            private set;
        }

        public bool Modified
        {
            get
            {
                return modified;
            }
            internal set
            {
                modified = value;
                var handler = ModifiedChanged;
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }

        public String Path
        {
            get
            {
                return path;
            }
        }

        #endregion

        #region Public Constants

        public const String WorkspaceExtension = "fusw";

        #endregion

        #region Public Events

        public event EventHandler ModifiedChanged;

        #endregion

        #region Private Fields

        private IProgrammer programmer;

        private IHardwareInterface hwInterface;

        private IHardwareAdapter adapter;

        private Options options;

        private static int workspaceCounter = 0;

        private bool modified = true;

        private String path;

        #endregion
    }
}